package com.ruoyi.system.controller;

import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.ip.IpUtils;
import com.ruoyi.system.domain.PageConfig;
import com.ruoyi.system.domain.PageTemplate;
import com.ruoyi.system.domain.PageVisit;
import com.ruoyi.system.service.IPageConfigService;
import com.ruoyi.system.service.IPageTemplateService;
import com.ruoyi.system.service.IPageVisitService;
import eu.bitwalker.useragentutils.UserAgent;

/**
 * 页面预览Controller（无需认证）
 * 
 * @author ruoyi
 * @date 2025-03-30
 */
@Anonymous
@RestController
@RequestMapping("/api/preview")
public class PagePreviewController
{
    @Autowired
    private IPageConfigService pageConfigService;
    
    @Autowired
    private IPageTemplateService pageTemplateService;
    
    @Autowired
    private IPageVisitService pageVisitService;

    /**
     * 获取页面配置和资源
     */
    @GetMapping("/{pageKey}")
    public AjaxResult getPageConfig(@PathVariable("pageKey") String pageKey, HttpServletRequest request)
    {
        // 查询已发布的页面配置
        PageConfig pageConfig = pageConfigService.selectPublishedPageConfigByKey(pageKey);
        if (pageConfig == null)
        {
            return AjaxResult.error("页面不存在或未发布");
        }
        
        // 获取模板信息
        PageTemplate template = pageTemplateService.selectPageTemplateById(pageConfig.getTemplateId());
        if (template == null)
        {
            return AjaxResult.error("模板不存在或已停用");
        }
        
        // 记录访问信息
        recordPageVisit(pageConfig.getId(), request);
        
        // 返回页面配置数据
        AjaxResult ajax = AjaxResult.success();
        ajax.put("pageConfig", pageConfig);
        ajax.put("template", template);
        
        return ajax;
    }
    
    /**
     * 获取模板信息
     */
    @GetMapping("/template/{templateId}")
    public AjaxResult getTemplate(@PathVariable("templateId") Long templateId)
    {
        PageTemplate template = pageTemplateService.selectPageTemplateById(templateId);
        if (template == null)
        {
            return AjaxResult.error("模板不存在");
        }
        return AjaxResult.success(template);
    }
    
    /**
     * 记录页面访问
     */
    @PostMapping("/visit/{pageKey}")
    public AjaxResult recordVisit(@PathVariable("pageKey") String pageKey, @RequestBody PageVisit visit)
    {
        // 查询已发布的页面配置
        PageConfig pageConfig = pageConfigService.selectPublishedPageConfigByKey(pageKey);
        if (pageConfig == null)
        {
            return AjaxResult.error("页面不存在或未发布");
        }
        
        // 设置页面ID
        visit.setPageId(pageConfig.getId());
        visit.setVisitTime(new Date());
        
        // 设置IP地址（如果前端未提供）
        if (visit.getVisitIp() == null || visit.getVisitIp().isEmpty())
        {
            visit.setVisitIp(IpUtils.getIpAddr(ServletUtils.getRequest()));
        }
        
        // 设置访客ID（如果前端未提供）
        if (visit.getVisitorId() == null || visit.getVisitorId().isEmpty())
        {
            visit.setVisitorId(generateVisitorId(ServletUtils.getRequest()));
            visit.setIsUnique("1");
        }
        
        // 保存访问记录
        pageVisitService.insertPageVisit(visit);
        
        return AjaxResult.success();
    }
    
    /**
     * 记录页面访问
     * 
     * @param pageId 页面ID
     * @param request 请求对象
     */
    private void recordPageVisit(Long pageId, HttpServletRequest request)
    {
        try
        {
            PageVisit visit = new PageVisit();
            visit.setPageId(pageId);
            visit.setVisitTime(new Date());
            visit.setVisitIp(IpUtils.getIpAddr(request));
            visit.setVisitUrl(request.getRequestURL().toString());
            
            // 获取访问设备信息
            String userAgent = request.getHeader("User-Agent");
            if (userAgent != null)
            {
                UserAgent agent = UserAgent.parseUserAgentString(userAgent);
                visit.setVisitBrowser(agent.getBrowser().getName());
                visit.setVisitOs(agent.getOperatingSystem().getName());
                visit.setVisitDevice(agent.getOperatingSystem().getDeviceType().getName());
            }
            
            // 获取来源
            String referer = request.getHeader("Referer");
            visit.setVisitSource(referer != null ? referer : "直接访问");
            
            // 设置访客ID（使用IP地址和User-Agent组合生成）
            String visitorId = generateVisitorId(request);
            visit.setVisitorId(visitorId);
            visit.setIsUnique("1"); // 默认设为唯一访客，实际应用中可以根据visitorId进一步判断
            
            // 异步保存访问记录
            pageVisitService.insertPageVisit(visit);
        }
        catch (Exception e)
        {
            // 记录日志但不影响正常访问
            System.out.println("记录访问信息失败: " + e.getMessage());
        }
    }

    /**
     * 生成访客唯一标识
     * 
     * @param request 请求对象
     * @return 访客ID
     */
    private String generateVisitorId(HttpServletRequest request)
    {
        // 组合IP地址、User-Agent、客户端信息等生成唯一标识
        String ip = request.getRemoteAddr();
        String userAgent = request.getHeader("User-Agent");
        String sessionId = request.getSession().getId();
        
        // 组合信息
        String visitorInfo = ip + "-" + userAgent + "-" + sessionId;
        
        try {
            // 使用MD5加密
            java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");
            byte[] array = md.digest(visitorInfo.getBytes("UTF-8"));
            
            // 转换为十六进制字符串
            StringBuilder sb = new StringBuilder();
            for (byte b : array) {
                sb.append(Integer.toHexString((b & 0xFF) | 0x100).substring(1, 3));
            }
            return sb.toString();
        } catch (Exception e) {
            // 如果加密失败，则返回原始组合信息
            return visitorInfo.hashCode() + "";
        }
    }
} 